package app

import "strings"

type ApplyOption interface {
	Apply(c *Command)
}

type Option func(c *Command)

func (opt Option) Apply(c *Command) {
	opt(c)
}

type OptionGroup []ApplyOption

func (opts OptionGroup) Apply(c *Command) {
	for _, opt := range opts {
		opt.Apply(c)
	}
}

func Apply(c *Command, cmdOpts ...ApplyOption) {
	for _, cmdOpt := range cmdOpts {
		cmdOpt.Apply(c)
	}
}

func Use(use string, alias ...string) ApplyOption {
	return Option(func(c *Command) {
		c.Use = use
		if len(alias) > 0 {
			c.Aliases = alias
		}
	})
}

func Alias(alias ...string) ApplyOption {
	return Option(func(c *Command) {
		c.Aliases = alias
	})
}

func Version(version string) ApplyOption {
	return Option(func(c *Command) { c.Version = version })
}

func Comment(short string, long ...string) ApplyOption {
	return Option(func(c *Command) {
		if short != "" {
			c.Short = short
		}
		if len(long) > 0 {
			c.Long = strings.Join(long, "\n")
		}
	})
}

func Flags(appFlag func(fs *FlagSet)) ApplyOption {
	return Option(func(c *Command) {
		appFlag(c.Flags())
	})
}

func PersistentFlags(appFlag func(fs *FlagSet)) ApplyOption {
	return Option(func(c *Command) {
		appFlag(c.PersistentFlags())
	})
}

func SubCommand(commands ...*Command) ApplyOption {
	return Option(func(c *Command) { c.AddCommand(commands...) })
}
